/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "RenderTarget.h"
#include "Hardware.h"
#include <Gluck.h>

namespace liba
{
namespace lib3d
{
namespace hard
{
namespace marmalade
{

extern Texture * last_texture;
	
RenderTarget::RenderTarget(Hardware * hardware, const Atom & name, int width, int height) 
	: hard::RenderTarget(name)
	, hard::TextureBase(1, pictureformat::A8R8G8B8, width, height)
	, hardware(hardware)
{
	glGenTextures(1, &texture);
	if(!texture)
		THROW(Gluck(__FUNCTION__, "create_internal_texture() failed"));
	
	glGenFramebuffersOES(1, &frameBuffer);
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, frameBuffer);
	glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);

	glGenRenderbuffersOES(1, &depthBuffer);
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthBuffer);
	glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, get_width(), get_height());
	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthBuffer);
	
	if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
		THROW(Gluck(__FUNCTION__, "Render target creation failed"));
}

RenderTarget::~RenderTarget()
{
	hardware->remove_render_target(this);
	release();
}

bool RenderTarget::start_scene(double left, double right, double top, double bottom)
{
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, frameBuffer);
	return true;
}

const int RenderTarget::get_width()const
{
	return (int) original_width;
}
	
const int RenderTarget::get_height()const
{
	return (int) original_height;
}
	
bool RenderTarget::is_valid()
{
	return true;
}

bool RenderTarget::set_in_hardware(int stage)
{
	last_texture = NULL;
	
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	
	return true;
}

void RenderTarget::get_data()
{
}

void RenderTarget::invalidate()
{
	release();
}

void RenderTarget::release()
{
	glBindTexture(GL_TEXTURE_2D, 0);
	last_texture = NULL;
	
	if(texture)
		glDeleteTextures(1, &texture);
	
	if(frameBuffer)
		glDeleteFramebuffersOES(1, &frameBuffer);
	
	if(depthBuffer)
		glDeleteRenderbuffersOES(1, &depthBuffer);
}

} // namespace marmalade
} // namespace hard
} // namespace lib3d
} // namespace liba

